#include <iostream>
#include <functional>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wssrv_t;

void print(const char* str)
{
    std::cout << str << std::endl;
}

void http_handler(wssrv_t* srv,websocketpp::connection_hdl hdl)
{
    //回复简单的信息
    //获取连接对象
    wssrv_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << "body: " << conn->get_request_body() << std::endl;

    //获取http请求对象
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string str = "<html><body><h1>hello world</h1><body></html>";
    conn->set_body(str);
    conn->set_status(websocketpp::http::status_code::ok);
    conn->append_header("Content-type", "text/html");

    //定时器的使用
    //单位ms,回调函数
    wssrv_t::timer_ptr tp = srv->set_timer(5000, std::bind(print, "hello world"));
    //注意：撤销一个定时任务，会立即执行这个任务
    tp->cancel();
}

void wsopen_handler(wssrv_t* srv,websocketpp::connection_hdl hdl)
{
    std::cout << "websocket握手成功" << std::endl;
}

void wsclose_handler(wssrv_t* srv, websocketpp::connection_hdl hdl)
{
    std::cout << "websocket连接关闭" << std::endl;
}

void wsmessage_handler(wssrv_t* srv, websocketpp::connection_hdl hdl, wssrv_t::message_ptr message_ptr)
{
    wssrv_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    //接收信息并且回显
    std::cout << message_ptr->get_payload() << std::endl;

    std::string rsp = "client say: " + message_ptr->get_payload();
    conn->send(rsp, websocketpp::frame::opcode::text);
}

int main()
{
    //1.实例化server对象
    wssrv_t wssrv;
    //2.设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3.初始化asio调度器
    wssrv.init_asio();
    //端口复用
    wssrv.set_reuse_addr(true);
    //4.设置回调函数
    wssrv.set_http_handler(bind(http_handler, &wssrv, std::placeholders::_1));
    wssrv.set_open_handler(bind(wsopen_handler, &wssrv, std::placeholders::_1));
    wssrv.set_close_handler(bind(wsclose_handler, &wssrv, std::placeholders::_1));
    wssrv.set_message_handler(bind(wsmessage_handler, &wssrv, std::placeholders::_1, std::placeholders::_2));
    //5.设置监听端口
    wssrv.listen(8888);
    //6.开始获取新连接
    wssrv.start_accept();
    //7.启动服务器
    wssrv.run();
    return 0;
}